Read() causing Exception error

Hello,

I have a DXL script with stability problems : in some cases, it crashes with an Exception error. I have managed to use the DXL trace to identify the failing code line and it is :
 

if(!open(mn)) read(fullName(mn),false)

 


where mn is declared as :
ModName_ mn

Any idea about the crash root cause ??

Any tip about methodology and/or tools for debugging this kind of issue is also welcome ...

Thanks in advance,

Servanne.

 


sdauphin - Thu Sep 16 08:06:55 EDT 2010

Re: Read() causing Exception error
doors36677 - Thu Sep 16 08:12:13 EDT 2010

Try replacing ModName_ mn

With Module m

Re: Read() causing Exception error
SystemAdmin - Thu Sep 16 08:32:43 EDT 2010

Is the module to which mn refers to deleted? Or is the mn reference null? Are you checking for these?

Re: Read() causing Exception error
sdauphin - Thu Sep 16 09:03:29 EDT 2010

SystemAdmin - Thu Sep 16 08:32:43 EDT 2010
Is the module to which mn refers to deleted? Or is the mn reference null? Are you checking for these?

@Pekka :
No, I am not checking these points.

This is the entire loop code :

// for each link arriving on o and following rlm link module
        for lref in o <- "rlm" do {
                        // Get the source module name
                        mn = source(lref)
                        // opens the module in read mode and invisible if it is not open
                        if(!open(mn)) {
                                read(fullName(mn),false)
                        }
                }

 


I am just trying to open all the modules containing objects that are linked to current object o by incoming links.

In the tests I am doing, the linked modules are not deleted. Should I add some checks in this context ?

 

Re: Read() causing Exception error
Mathias Mamsch - Thu Sep 16 09:45:00 EDT 2010

sdauphin - Thu Sep 16 09:03:29 EDT 2010

@Pekka :
No, I am not checking these points.

This is the entire loop code :

// for each link arriving on o and following rlm link module
        for lref in o <- "rlm" do {
                        // Get the source module name
                        mn = source(lref)
                        // opens the module in read mode and invisible if it is not open
                        if(!open(mn)) {
                                read(fullName(mn),false)
                        }
                }

 


I am just trying to open all the modules containing objects that are linked to current object o by incoming links.

In the tests I am doing, the linked modules are not deleted. Should I add some checks in this context ?

 

When your code crashes that usually means, that one variable contains invalid data. Sometimes your code crashes, because you did something to corrupt your memory a few lines above, but the crash occurs later, when you access the corrupt memory. For your code a typical way to make the code crash is to close or change the edit modue of the module that contains the object o.

For me there are two plausible reasons that your code crashes with an exception:
a) Your ModName_ variable memory got corrupted (Could not see how or why? Eventually by really messing up the DOORS heap)
b) Your Object variable memory got corrupted (more plausible, maybe the module is closed, or the edit mode changed?)

You probably did this in some part of the code, that you have not posted, or at least I could not spot a reason. In most cases it is so hard to find bugs, since we look at the wrong place. Can you post a more complete code example?

Regards, Mathias

Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

Re: Read() causing Exception error
sdauphin - Thu Sep 16 10:57:26 EDT 2010

Mathias Mamsch - Thu Sep 16 09:45:00 EDT 2010
When your code crashes that usually means, that one variable contains invalid data. Sometimes your code crashes, because you did something to corrupt your memory a few lines above, but the crash occurs later, when you access the corrupt memory. For your code a typical way to make the code crash is to close or change the edit modue of the module that contains the object o.

For me there are two plausible reasons that your code crashes with an exception:
a) Your ModName_ variable memory got corrupted (Could not see how or why? Eventually by really messing up the DOORS heap)
b) Your Object variable memory got corrupted (more plausible, maybe the module is closed, or the edit mode changed?)

You probably did this in some part of the code, that you have not posted, or at least I could not spot a reason. In most cases it is so hard to find bugs, since we look at the wrong place. Can you post a more complete code example?

Regards, Mathias


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

Mathias,

I am attaching the full script as a zip file (~ 600 lines). There is a small readme file, I hope it contains enough information.

The extract is coming from function initLinkedObjectList in objectModified.dxl, but if I understand you well, the root cause of the problem may be anywhere, right ?

I hope you can point me to weak code statements.

Best regards,

Servanne.
Attachments

attachment_14532309_Reuse_DXL_Scripts.zip

Re: Read() causing Exception error
Mathias Mamsch - Thu Sep 16 12:14:36 EDT 2010

sdauphin - Thu Sep 16 10:57:26 EDT 2010
Mathias,

I am attaching the full script as a zip file (~ 600 lines). There is a small readme file, I hope it contains enough information.

The extract is coming from function initLinkedObjectList in objectModified.dxl, but if I understand you well, the root cause of the problem may be anywhere, right ?

I hope you can point me to weak code statements.

Best regards,

Servanne.

Two things come to my eye when skimming through your code:

1. ... Link deletion in loop ... objectModified.dxl:144

for l in o1 -> rlmn do {
    delete(l) 
}

 


Don't do that. Always use

 

 

Skip sk = create(); for l in o1->rlmn do { put (sk, l,l) }; for l in sk do delete l



Since deletions that modify the loop object most of the times brings DOORS to its knees and might be responsible for heap corruption.

2. When I recognize the crash code right it should be objectModified.dxl:304. I checked the caller and found:



 

 

 


objectModified.dxl:280 -> void initLinkedObjectList (DBE listDBE, Object o)
...
objectModified.dxl:280 -> for lref in o <- fullName(rlm) do {
...
objectModified.dxl:300 -> mn = source(lref)
objectModified.dxl:304 -> if(!open(mn))
objectModified.dxl:305 -> m = read(fullName(mn),false) // boom!

 

 

 


...
objectModified.dxl:389 -> if(src_obj_is_new){
objectModified.dxl:391 -> saveObject(src_obj)
objectModified.dxl:392 -> }
...
objectModified.dxl:409 -> initLinkedObjectList (listDBE, src_obj)

 

 


{code}

saveObject(src_obj) does a unlockSaveSection src_obj. My guess is, that this invalidates the object handle, which you will only see once the object memory is reused by something other. Can you comment out the saveObject and check if the error disappears?

Regards, Mathias

 

 


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

 

Re: Read() causing Exception error
Mathias Mamsch - Thu Sep 16 12:21:38 EDT 2010

Mathias Mamsch - Thu Sep 16 12:14:36 EDT 2010

Two things come to my eye when skimming through your code:

1. ... Link deletion in loop ... objectModified.dxl:144

for l in o1 -> rlmn do {
    delete(l) 
}

 


Don't do that. Always use

 

 

Skip sk = create(); for l in o1->rlmn do { put (sk, l,l) }; for l in sk do delete l



Since deletions that modify the loop object most of the times brings DOORS to its knees and might be responsible for heap corruption.

2. When I recognize the crash code right it should be objectModified.dxl:304. I checked the caller and found:



 

 

 


objectModified.dxl:280 -> void initLinkedObjectList (DBE listDBE, Object o)
...
objectModified.dxl:280 -> for lref in o <- fullName(rlm) do {
...
objectModified.dxl:300 -> mn = source(lref)
objectModified.dxl:304 -> if(!open(mn))
objectModified.dxl:305 -> m = read(fullName(mn),false) // boom!

 

 

 


...
objectModified.dxl:389 -> if(src_obj_is_new){
objectModified.dxl:391 -> saveObject(src_obj)
objectModified.dxl:392 -> }
...
objectModified.dxl:409 -> initLinkedObjectList (listDBE, src_obj)

 

 


{code}

saveObject(src_obj) does a unlockSaveSection src_obj. My guess is, that this invalidates the object handle, which you will only see once the object memory is reused by something other. Can you comment out the saveObject and check if the error disappears?

Regards, Mathias

 

 


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

 

And since I cannot setup a test environment myself (got a project archive?) please tell exactly how to come to the exception! When you run the script on an object that has links? No links? was newly created? That will help find the way through the code. Regards, Mathias

Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

Re: Read() causing Exception error
llandale - Thu Sep 16 13:07:05 EDT 2010

Mathias Mamsch - Thu Sep 16 12:14:36 EDT 2010

Two things come to my eye when skimming through your code:

1. ... Link deletion in loop ... objectModified.dxl:144

for l in o1 -> rlmn do {
    delete(l) 
}

 


Don't do that. Always use

 

 

Skip sk = create(); for l in o1->rlmn do { put (sk, l,l) }; for l in sk do delete l



Since deletions that modify the loop object most of the times brings DOORS to its knees and might be responsible for heap corruption.

2. When I recognize the crash code right it should be objectModified.dxl:304. I checked the caller and found:



 

 

 


objectModified.dxl:280 -> void initLinkedObjectList (DBE listDBE, Object o)
...
objectModified.dxl:280 -> for lref in o <- fullName(rlm) do {
...
objectModified.dxl:300 -> mn = source(lref)
objectModified.dxl:304 -> if(!open(mn))
objectModified.dxl:305 -> m = read(fullName(mn),false) // boom!

 

 

 


...
objectModified.dxl:389 -> if(src_obj_is_new){
objectModified.dxl:391 -> saveObject(src_obj)
objectModified.dxl:392 -> }
...
objectModified.dxl:409 -> initLinkedObjectList (listDBE, src_obj)

 

 


{code}

saveObject(src_obj) does a unlockSaveSection src_obj. My guess is, that this invalidates the object handle, which you will only see once the object memory is reused by something other. Can you comment out the saveObject and check if the error disappears?

Regards, Mathias

 

 


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

 

... followed by "flushDeletions()".

Re: Read() causing Exception error
llandale - Thu Sep 16 13:11:46 EDT 2010

sdauphin - Thu Sep 16 09:03:29 EDT 2010

@Pekka :
No, I am not checking these points.

This is the entire loop code :

// for each link arriving on o and following rlm link module
        for lref in o <- "rlm" do {
                        // Get the source module name
                        mn = source(lref)
                        // opens the module in read mode and invisible if it is not open
                        if(!open(mn)) {
                                read(fullName(mn),false)
                        }
                }

 


I am just trying to open all the modules containing objects that are linked to current object o by incoming links.

In the tests I am doing, the linked modules are not deleted. Should I add some checks in this context ?

 

Mathias is probably right.

But its possible the default view in that module has layout code that causes the crash. Before you "read", ack the fullname. When you find out which module triggers the crash, try opening it first manually then via a DXL read statement. You may also want to split the fullname up from the read: Name = fullName(mn).

If there is an issue with the view, you can bypass it with:
read(fullName(mn), false, true)
which loads the 'standard' view.

  • Louie

Re: Read() causing Exception error
sdauphin - Thu Sep 16 14:07:40 EDT 2010

llandale - Thu Sep 16 13:11:46 EDT 2010
Mathias is probably right.

But its possible the default view in that module has layout code that causes the crash. Before you "read", ack the fullname. When you find out which module triggers the crash, try opening it first manually then via a DXL read statement. You may also want to split the fullname up from the read: Name = fullName(mn).

If there is an issue with the view, you can bypass it with:
read(fullName(mn), false, true)
which loads the 'standard' view.

  • Louie

Hello,

I have tried the different suggestions :
  • deletion of links
  • comment out saveObject function calls
  • use read(fullName(mn), false, true)

Let me describe one scenario that crashes consistently :
  • Open exclusive the pool module. The other modules are closed.
  • point on an existing object with 3 incoming links : 2 from project-module #1, 1 from project-module #2.
  • modify the Object text of this object.
  • the trigger fires and I get the dialog box with the list of 3 linked objects.
  • I select them all and click apply.
  • the synchronization goes well, and I get the success message box.
  • Then, I try to redo the same steps : I modify the Object Text of the same object, the trigger fires and DOORS crashes with an exception access error message on the read statement.

I have indeed some DXL attributes in my views, with cross-references between pool and project modules (generated with traceability wizard, then converted to DXL attributes).

I have noticed something weird : when I enable the TRACE variable and display the status of the project modules (if (TRACE) print "Open = " open(mn) "\n"), I can see that the project modules are already "open" (in background) on the first run. On the second run, they are not opened, since I have closed them at the end of the first run with the closeInvisibleModules function.

Why are they open from the start ? It is due to the DXL attributes ?

Nevertheless, if I open all the modules (pool + projects) in exclusive before trying to make changes, I still get a crash, even if it happens a bit later ...

Best regards,
Servanne.

Re: Read() causing Exception error
sdauphin - Fri Sep 17 05:48:51 EDT 2010

sdauphin - Thu Sep 16 14:07:40 EDT 2010
Hello,

I have tried the different suggestions :

  • deletion of links
  • comment out saveObject function calls
  • use read(fullName(mn), false, true)

Let me describe one scenario that crashes consistently :
  • Open exclusive the pool module. The other modules are closed.
  • point on an existing object with 3 incoming links : 2 from project-module #1, 1 from project-module #2.
  • modify the Object text of this object.
  • the trigger fires and I get the dialog box with the list of 3 linked objects.
  • I select them all and click apply.
  • the synchronization goes well, and I get the success message box.
  • Then, I try to redo the same steps : I modify the Object Text of the same object, the trigger fires and DOORS crashes with an exception access error message on the read statement.

I have indeed some DXL attributes in my views, with cross-references between pool and project modules (generated with traceability wizard, then converted to DXL attributes).

I have noticed something weird : when I enable the TRACE variable and display the status of the project modules (if (TRACE) print "Open = " open(mn) "\n"), I can see that the project modules are already "open" (in background) on the first run. On the second run, they are not opened, since I have closed them at the end of the first run with the closeInvisibleModules function.

Why are they open from the start ? It is due to the DXL attributes ?

Nevertheless, if I open all the modules (pool + projects) in exclusive before trying to make changes, I still get a crash, even if it happens a bit later ...

Best regards,
Servanne.

I have made some progress this morning :

I replaced these statements (in synchronizeOrReplace function):

objects_to_synchronize_skip = linked_objects_skip
modules_to_synchronize_skip = linked_modules_skip

 


by this piece of code :

 

 

 

int i = 0
        Object temp_o
                for temp_o in linked_objects_skip do {
                        put (objects_to_synchronize_skip, i++, temp_o)
                }
                i = 0
                ModName_ tmod
                for tmod in linked_modules_skip do {
                        put (modules_to_synchronize_skip, i++, tmod)
                }



Now the script is much more stable, but I was still getting some crashes.

So, I commented out the calls to closeInvisibleModules function, and since then, I didn't get any crash when the script was running, but only when closing the pool module.

Could you have a look at that function (in tools.dxl) ? Is it closing more files than required ? How would you implement it ?

Best regards,

Servanne.



 

 

Re: Read() causing Exception error
sdauphin - Fri Sep 17 05:51:22 EDT 2010

sdauphin - Fri Sep 17 05:48:51 EDT 2010

I have made some progress this morning :

I replaced these statements (in synchronizeOrReplace function):

objects_to_synchronize_skip = linked_objects_skip
modules_to_synchronize_skip = linked_modules_skip

 


by this piece of code :

 

 

 

int i = 0
        Object temp_o
                for temp_o in linked_objects_skip do {
                        put (objects_to_synchronize_skip, i++, temp_o)
                }
                i = 0
                ModName_ tmod
                for tmod in linked_modules_skip do {
                        put (modules_to_synchronize_skip, i++, tmod)
                }



Now the script is much more stable, but I was still getting some crashes.

So, I commented out the calls to closeInvisibleModules function, and since then, I didn't get any crash when the script was running, but only when closing the pool module.

Could you have a look at that function (in tools.dxl) ? Is it closing more files than required ? How would you implement it ?

Best regards,

Servanne.



 

 

I'm posting the code here for more convenience :

/**
* Closes all the modules opened by a script, so which are not visible.
*/
void closeInvisibleModules(){
    Module m
        // for each open module in the database (with read access from the current user)
        for m in database do {
                // if m is a formal module and is not visible, close it
                if(type(m)=="Formal" && !isVisible(m)) close(m,false)         
        }
}

Re: Read() causing Exception error
Mathias Mamsch - Fri Sep 17 07:24:27 EDT 2010

sdauphin - Fri Sep 17 05:51:22 EDT 2010

I'm posting the code here for more convenience :

/**
* Closes all the modules opened by a script, so which are not visible.
*/
void closeInvisibleModules(){
    Module m
        // for each open module in the database (with read access from the current user)
        for m in database do {
                // if m is a formal module and is not visible, close it
                if(type(m)=="Formal" && !isVisible(m)) close(m,false)         
        }
}

Servanne, you have to be careful with closing modules. Closing a module will invalidate all object and module handles and any access to them will lead to a crash. So

1. Close the modules only if you don't access any reference of the modules afterwards (especially all the ones you stored in the skips)

2. You are doing it again :-)
 

for module in database do { ... close m ... } // ouch!

 


don't modify the database object while you are iterating over it. Do:

 

 

 

Skip sk = create(); 
for module in database do { ... put (sk, module, module) }; 
for module in sk do close module; 
delete sk



Regards, Mathias



 

 

 

 


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

 

 

Re: Read() causing Exception error
llandale - Fri Sep 17 13:21:25 EDT 2010

sdauphin - Fri Sep 17 05:48:51 EDT 2010

I have made some progress this morning :

I replaced these statements (in synchronizeOrReplace function):

objects_to_synchronize_skip = linked_objects_skip
modules_to_synchronize_skip = linked_modules_skip

 


by this piece of code :

 

 

 

int i = 0
        Object temp_o
                for temp_o in linked_objects_skip do {
                        put (objects_to_synchronize_skip, i++, temp_o)
                }
                i = 0
                ModName_ tmod
                for tmod in linked_modules_skip do {
                        put (modules_to_synchronize_skip, i++, tmod)
                }



Now the script is much more stable, but I was still getting some crashes.

So, I commented out the calls to closeInvisibleModules function, and since then, I didn't get any crash when the script was running, but only when closing the pool module.

Could you have a look at that function (in tools.dxl) ? Is it closing more files than required ? How would you implement it ?

Best regards,

Servanne.



 

 

Assigning a Skip to a Skip is creating an alias; it does NOT make a copy like you do in your changed manual code.

void    PrintSkip(string Label, Skip skp)
{   string Data
    for Data in skp do
    {  print Label "\t" Data "\n"
    }
}
 
Skip skp1 = createString()
put(skp1, "1-1", "1-1")
put(skp1, "1-2", "1-2")
 
Skip skp2 = createString()
put(skp2, "2-1", "2-1")
 
 
PrintSkip("skp1", skp1)
PrintSkip("skp2", skp2)
 
Skip skp3 = skp2       // Makes alias
PrintSkip("skp3", skp3) // prints 2-1
 
put(skp3, "3-1", "3-1")
PrintSkip("skp2", skp2) // prints 2-1; 3-1
 
Skip    skp4 = skp1
skp1 = skp2
PrintSkip("skp1", skp1) // prints 2-1; 3-1
 
delete(skp2)
delete(skp4)     // originally skp1


Produces this output:

 

skp1    1-1
skp1    1-2
skp2    2-1
skp3    2-1
skp2    2-1
skp2    3-1
skp1    2-1
skp1    3-1

 

 

  • Louie